
#include <cstdlib>
#include "Gameplay/Piece.h"

namespace Gameplay {

// Move towards a desirect direction

Piece::Piece(int id, const Misc::Frame & pieceFrame, const Misc::Frame & boardFrame, const Engine::Resource::Graphic & targetGraphic) :
	Visual("gameplay"),
	Reason("gameplay"),
	Sense("gameplay"),

	pieceID(id),
	pieceFrame(pieceFrame),
	boardFrame(boardFrame),
 	gfx(targetGraphic.slice((id & 0x0000ff00) >> 8, (id & 0x000000ff)), 2),
	shadowGfx("pieceShadow50x50", "", 1),
	retryAnimation(10)
 {
	float fx = pieceFrame.w/250.0f;
	float fy = pieceFrame.h/250.0f;
	Misc::Vector2d v;
	/* FIXME: change these magic values */
	row = -1;
	column = 4;//(rand() % (boardFrame.w/pieceFrame.w));

	gfx.setPadding(boardFrame.x, boardFrame.y);

	movement.setMaxSpeed(200.0f);
	movement.setAccel(200.0f);
	
	piecePosition.w = pieceFrame.w;
	piecePosition.h = pieceFrame.h;
	v.y = 50.0 - boardFrame.y; v.x = 112.0 - boardFrame.x;
	movement.setDeparture(v);

	v.x = column*piecePosition.w;
	v.y = row*piecePosition.h;
	movement.setDestination(v);

	
	char shadowGfxName[255];
	std::sprintf(shadowGfxName, "pieceShadow%dx%d", pieceFrame.w, pieceFrame.h);
	shadowGfx = Engine::Resource::Graphic(shadowGfxName, "", 1);
	shadowGfx.setPadding(boardFrame.x, boardFrame.y);
	shadowGfx.setFrameSize(pieceFrame.w*3, pieceFrame.h*3); /* shadow pics are 3 times bigger than the piece frame */
	//retryGfx.setFrameSize(250.0*fx, 250*fy);
	//retryAnimation.setFPS(24);
	retryAnimation.setFrame(9);
	//retryAnimation.setFPS(0);
	//retryAnimation.setWrap(false);
}

// Builds a piece based and give it specific ID

Piece::~Piece(){
}

// Reset the piece.
void Piece::retry() {
  	Misc::Vector2d v;
	/* FIXME: change these magic values */
	row = -1;
	column = (rand() % (boardFrame.w/pieceFrame.w));

	retryAnimation.setFrame(0);
	
	v.y = row*piecePosition.h;
	v.x = column*piecePosition.w;
	movement.setDestination(v);
}

void Piece::turn(Misc::Direction direction) {
}

void Piece::move(Misc::Direction direction) {
  	switch (direction) {
		case Misc::DIRECTION_LEFT:
			column--;
			break;

		case Misc::DIRECTION_RIGHT:
			column++;
			break;

		case Misc::DIRECTION_UP:
			row--;
			break;

		case Misc::DIRECTION_DOWN:
			row++;
			break;
	}
	
	Misc::Vector2d v;
	v.x = column*piecePosition.w;
	v.y = row*piecePosition.h;
	movement.setDestination(v);
}

void Piece::pulse(int delta) {
	movement.update(delta, true);
  	Misc::Vector2d v = movement.readLocation();
	retryAnimation.update(delta);
	int frame = retryAnimation.readFrame();
	gfx.setPosition((int)v.x, (int)v.y);
	shadowGfx.setPosition(((int)v.x)-pieceFrame.w, ((int)v.y)-pieceFrame.h);
	shadowGfx.setFrame(frame, 0);
	std::printf("past-the-half[%d] accel[%.2f] deacc[%.2f] spd[%.2f/%.2f] x[%.0f->%.0f/%.0f] y[%.0f->%.0f/%.0f] s[%.2f/%.2f!%.2f,%.2f]\n",
				movement.position.distance(movement.departure) > movement.departure.distance(movement.destination)/2.0f,
				movement.acceleration, movement.friction,
				movement.speed, movement.maxSpeed,
				movement.departure.x, movement.position.x, movement.destination.x,
				movement.departure.y, movement.position.y, movement.destination.y,
				movement.position.distance(movement.departure), movement.totalDistance, movement.distanceToCruise, movement.distanceToBreak);
	//retryGfx.setCenter(piecePosition.x - piecePosition.w/2, piecePosition.y - piecePosition.h/2);
	//retryGfx.setFrame(frame, 0);
}

Engine::Resource::GraphicList Piece::display() {
	Engine::Resource::GraphicList gfxList;
	gfxList.push_back(&gfx);
	gfxList.push_back(&shadowGfx);
	return gfxList;
}


} // namespace Gameplay
